package failover

import (
	"context"
	"gitee.com/chicken-c/go-learn/webook/internal/service/sms"
	"sync/atomic"
)

type TimeoutFailoverSMSService struct {
	srvs []sms.Service

	//超时次数
	cnt int64
	//当前下标
	idx int64

	//阈值
	threshold int64
}

func (t *TimeoutFailoverSMSService) Send(ctx context.Context, tqlId string, args map[string]string, number string) error {
	cnt := atomic.LoadInt64(&t.cnt)
	idx := atomic.LoadInt64(&t.idx)

	//超过阈值，进行切换
	if cnt >= t.threshold {
		newIdx := (idx + 1) % (int64)(len(t.srvs))
		//CAS操作
		if atomic.CompareAndSwapInt64(&t.idx, idx, newIdx) {
			//idx交换成功,重制超时次数
			atomic.StoreInt64(&t.cnt, 0)
		}
	}

	err := t.srvs[t.idx].Send(ctx, tqlId, args, number)
	switch err {
	case nil:
		//发送成功,清空连续超时次数
		atomic.StoreInt64(&t.cnt, 0)
	case context.DeadlineExceeded:
		//超时,增加超时次数
		atomic.AddInt64(&t.cnt, 1)
	default:
		//其他错误，这里可以进行直接切换。也可以进行别的处理
	}

	return err
}
